/*******************************************************************************
 * Copyright (c) 2010 Mikhail Garber.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License (LGPL)
 * which accompanies this distribution
 * 
 * Contributors:
 *     Mikhail Garber - initial API and implementation
 ******************************************************************************/
package plumber.flow;


import org.slf4j.LoggerFactory;

import plumber.common.HasSetup;
import plumber.common.Utils;
import plumber.component.ClasspathComponentManager;
import plumber.component.ComponentManager;
import plumber.model.Flow;
import plumber.model.FlowStep;

/**
 * Flow Manager is responsible for locating of Steps
 *
 */
public class FlowManager implements HasSetup {

	
	private FlowValidator validator = new DefaultFlowValidator();
	private ComponentManager finder = new ClasspathComponentManager();
	private FlowLocator flowLocator;
	

	public FlowLocator getFlowLocator() {
		return flowLocator;
	}

	public void setFlowLocator(FlowLocator flowLocator) {
		this.flowLocator = flowLocator;
	}

	public void setValidator(FlowValidator validator) {
		this.validator = validator;
	}

	public void setFinder(ComponentManager finder) {
		this.finder = finder;
	}

	

	@Override
	/**
	 * load and validate flows on startup
	 */
	public void setup() {
		Utils.validatePresentCollection(flowLocator.getFlows(), "flows");
		Utils.validatePresent(finder, "finder");
		
		for(Flow flow : flowLocator.getFlows()) {
			validator.validate(flow, finder);			
		}
		LoggerFactory.getLogger(this.getClass()).info("validated all flows");
	}
	
	/**
	 * find a Flow Step
	 * @param flowName
	 * @param id
	 * @return matching FlowStep or null 
	 */
	public FlowStep findStepById(String flowName, String id) {
		LoggerFactory.getLogger(this.getClass()).info("looking for flow:" + flowName + ", id:" + id);
		for(Flow flow : flowLocator.getFlows()) {
			LoggerFactory.getLogger(this.getClass()).info("flow:" + flow);
			if(!flowName.equals(flow.getName())) {
				continue;
			}
			for(FlowStep step : flow.getSteps()) {
				if(step.getId().equals(id)) {
					return step;
				}
			}
		}
		return null;
	}
	
	/**
	 * find first Step in a work Flow
	 * @param name of the work Flow
	 * @return first step or null
	 */
	public FlowStep findFirstStepByFlowName(String name) {
		for (Flow flow : flowLocator.getFlows()) {
			if (flow.getName().equals(name)) {
				return flow.getFirstStep();
			}
		}
		return null;
	}

	@Override
	public void shutdown() {
	
		
	}
	
	
	
}
